import React, { useRef, useEffect } from 'react';
import ReactDOM from 'react-dom';

var styles = {"test":"test_test__3XED4","box":"test_box__3nx3q"};

function uuid() {
  function S4() {
    return ((1 + Math.random()) * 0x10000 | 0).toString(16).substring(1);
  }

  const str = S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4();
  return str;
}

const list = [];

for (let index = 0; index < 10; index++) {
  list.push({
    id: uuid(),
    index
  });
}

let lastIndex = -1;

function Index() {
  const listRef = useRef(null);
  const ref = useRef(null);
  const lastMoveIndex = useRef(0);
  const allHeight = useRef([]);

  const getIndex = y => {
    const hs = allHeight.current;

    if (hs && hs.length) {
      for (let i = 0; i < hs.length; i++) {
        let item = hs[i];

        if (y < item) {
          return i;
        }
      }
    }

    return -1;
  };

  const mousedownListener = e => {
    ref.current = e.target;
  };

  const swapElements = (a, b) => {
    if (a == b) return;
    var bp = b.parentNode,
        ap = a.parentNode;
    var an = a.nextElementSibling,
        bn = b.nextElementSibling;
    if (an == b) return bp.insertBefore(b, a);
    if (bn == a) return ap.insertBefore(a, b);
    if (a.contains(b)) return ap.insertBefore(b, a), bp.insertBefore(a, bn);else return bp.insertBefore(a, b), ap.insertBefore(b, an);
  };

  const mousemoveListener = e => {
    if (ref.current) {
      const moveIndex = getIndex(e.clientY);

      if (moveIndex !== lastIndex) {
        console.log(moveIndex);
        lastMoveIndex.current = moveIndex;
        const $dom = listRef?.current;
        const children = $dom.childNodes;
        const $modeCurrent = children[moveIndex];
        const hs = allHeight.current;
        const moveY = hs[moveIndex] - (moveIndex > 0 ? hs[moveIndex - 1] : hs[0]);
        console.log(moveY);
        ref.current.style = `opacity:0`;
        setTimeout(() => {
          swapElements($modeCurrent, children[moveIndex > 0 ? moveIndex - 1 : 0]);
          $modeCurrent.style = `transform:'';transition:''`;
        }, 0.5 * 1000);
        $modeCurrent.style = `transform:translateY(-${moveY}px);transition:all 0.5s;`;
      }

      lastIndex = moveIndex;
    }
  };

  const mouseupListener = e => {
    ref.current.style = `opacity:1`;
    ref.current = null;
    console.log("mouseupListener", e);
  };

  useEffect(() => {
    const $dom = listRef?.current;
    const children = $dom.childNodes;
    let _allHeight = [];

    for (let i = 0; i < children.length; i++) {
      console.log(children[i]);
      const currentDom = children[i];

      if (currentDom) {
        const {
          top,
          left,
          bottom,
          right,
          height,
          width
        } = currentDom.getBoundingClientRect();

        if (i === 0) {
          _allHeight[0] = height;
        } else {
          _allHeight[i] = _allHeight[i - 1] + height;
        }
      }
    }

    allHeight.current = _allHeight;
  }, [list]);
  useEffect(() => {
    const $dom = listRef?.current;

    if ($dom) {
      $dom.addEventListener("mousedown", mousedownListener);
      $dom.addEventListener("mousemove", mousemoveListener);
      $dom.addEventListener("mouseup", mouseupListener);
    }
  });
  return React.createElement("div", {
    ref: listRef,
    className: styles.test
  }, list.map((item, index) => React.createElement("div", {
    key: item?.id,
    className: styles.box
  }, index)));
}

ReactDOM.render(React.createElement(Index, null), document.getElementById("root"));
